#ifndef _I2C_MASTER_H_
#define _I2C_MASTER_H_

#include "H/Function_Init.H" 
//功能说明：
//STEP1~5 实现I2C主机P03为SDA，P04为SCL，通讯地址0x20，速率100KHz，I2C数据收发

/***********************************************************************************************
STEP_1：D_OSCD时钟烧录选项设置，决定I2C时钟源
        在Function_Init.H文件设置(请务必与烧录选项保持一致)
        OSCD=2T  速率范围63 ~400K  
        OSCD=4T  速率范围32~200K   （默认）
        OSCD=8T  速率范围16~100K
        OSCD=16T 速率范围8~50K 
************************************************************************************************/       

/***********************************************************************************************
STEP_2：I2C_MASTER主机初始化 
        uint R_SPD     I2C速率
***********************************************************************************************/
#define  D_M_SDA    0    //0：P03为SDA  1：P31为SDA
#define  D_M_SCL    0    //0：P04为SCL  1：P30为SCL

//      I2C_MASTER_INIT(uint R_SPD);
//      I2C_MASTER_INIT(100);         //速率100KHz

/***********************************************************************************************
STEP_3：I2C中断服务函数，置于INTERRUPT.C        
***********************************************************************************************/
//      I2C_MASTER_INT();      //置于中断void I2C() interrupt 7中   I2C中断服务函数

/***********************************************************************************************
STEP_4：主机模式，实现I2C主机发送/接收，采用I2C中断处理方式
        uchar R_ADDR         //通讯地址 0~0x7FH
        uchar *P_DATA        //指向数据存储地址
        uchar R_LENGTH       //通讯数据长度
        bit F_MODE           //0：主机发送   1：主机接收
***********************************************************************************************/
#define D_I2C_M_DATA_LENGTH   16    //A_I2C_M_DATA数组长度

//      I2C_MASTER_START(uchar R_ADDR,uchar *P_DATA,uchar R_LENGTH,bit F_MODE); //实现I2C主机发送/接收

//      主机发送
//      I2C_MASTER_START(0x20,&A_I2C_M_DATA,D_I2C_M_DATA_LENGTH,0); //通讯地址0x20，I2C发送数据存于A_I2C_M_DATA数组，通讯数据长度，主机发送模式

//      主机接收               
//      I2C_MASTER_START(0x20,&A_I2C_M_DATA,D_I2C_M_DATA_LENGTH,1); //通讯地址0x20,I2C接收数据存于A_I2C_M_DATA数组，通讯数据长度，主机接收模式   

//      标志，调用I2C_MASTER_START函数后用户自行判断，可死等或轮询判断
//      F_I2C_M          //1：总线空闲数据通讯完成  0：总线忙
//      F_I2C_M_ERR      //1：通讯错误  0：通讯正常
           
/***********************************************************************************************
STEP_5：通讯超时，I2C中断内计数清0
        超时范围设置1~255，超时时间=调用时间*R_OVERTIME
        超时标志：F_I2C_M_OVERTIME     
***********************************************************************************************/
//      I2C_M_OVERTIME(uchar R_OVERTIME);
//      I2C_M_OVERTIME(100);  //建议Timer0内调用

//      标志，调用I2C_M_OVERTIMEE函数后，在任意处自行判断，
//      F_I2C_M_OVERTIME    //1：通讯超时  0：未超时










/***********************************************************************************************
函数声明      函数声明      函数声明      函数声明
***********************************************************************************************/
void I2C_MASTER_INIT(uint R_SPD);
void I2C_M_STOP();
void I2C_M_START();    
void I2C_MASTER_Test();
void I2C_MASTER_START(uchar R_ADDR,uchar *P_DATA,uchar R_LENGTH,bit F_MODE);
void I2C_MASTER(uchar R_ADDR,uchar *P_DATA,uchar R_LENGTH,bit F_MODE);
void I2C_MASTER_INT();
bit  CHECK_MASTER_I2CESTA();
void I2C_M_OVERTIME(uchar R_OVERTIME);
/***********************************************************************************************
全局变量定义  
***********************************************************************************************/
#ifdef E_I2C_MASTER
  #define I2C_EXTERN
#else
  #define I2C_EXTERN   extern
#endif

I2C_EXTERN uchar R_I2C_M_ADDR;            //I2C通讯地址
I2C_EXTERN uchar *P_I2C_M_DATA;           //数据存储首地址
I2C_EXTERN uchar R_I2C_M_DATA_LENGTH;     //数据长度
I2C_EXTERN bit   F_I2C_M_MODE;            //0：主机发送   1：主机接收
I2C_EXTERN bit   F_I2C_M_STA;             //0：状态正确， 1：状态错误
I2C_EXTERN bit   F_I2C_M_ERR;             //0：通讯成功   1：通讯失败
I2C_EXTERN bit   F_I2C_M;                 //0：总线忙     1：总线空闲
//I2C_EXTERN bit   F_I2C_M_COM_OVER;        //0：
I2C_EXTERN bit   F_I2C_M_OVERTIME;        //0：未超时     1：超时
I2C_EXTERN uchar R_I2C_M_OVERTIME;       //超时计数
I2C_EXTERN uchar A_I2C_M_DATA[D_I2C_M_DATA_LENGTH];   //存储I2C数据







/************************************************
以下勿修改   以下勿修改   以下勿修改   以下勿修改
************************************************/

/************************************************
SFR宏定义    SFR宏定义    SFR宏定义    SFR宏定义
************************************************/
#if D_M_SDA==0
#define I2C_SDA         P03
#define I2C_SDA_IN      P0OE3_IN   //I2C_SDA做输入口
#define I2C_SDA_OUT     P0OE3_OUT  //I2C_SDA做输出口
#define I2C_SDA_PH_ON   P0PH3_ON   //I2C_SDA上拉使能
#define I2C_SDA_PH_OFF  P0PH3_OFF  //I2C_SDA上拉不使能
#define I2C_SDA_PD_ON   P0PD3_ON   //I2C_SDA下拉使能
#define I2C_SDA_PD_OFF  P0PD3_OFF  //I2C_SDA下拉不使能
#define I2C_SDA_OD_ON   P0OD3_ON   //I2C_SDA开漏使能
#define I2C_SDA_OD_OFF  P0OD3_OFF  //I2C_SDA开漏不使能
#endif
#if D_M_SDA==1
#define I2C_SDA         P31
#define I2C_SDA_IN      P3OE1_IN   //I2C_SDA做输入口
#define I2C_SDA_OUT     P3OE1_OUT  //I2C_SDA做输出口
#define I2C_SDA_PH_ON   P3PH1_ON   //I2C_SDA上拉使能
#define I2C_SDA_PH_OFF  P3PH1_OFF  //I2C_SDA上拉不使能
#define I2C_SDA_PD_ON   P3PD1_ON   //I2C_SDA下拉使能
#define I2C_SDA_PD_OFF  P3PD1_OFF  //I2C_SDA下拉不使能
#define I2C_SDA_OD_ON   P3OD1_ON   //I2C_SDA开漏使能
#define I2C_SDA_OD_OFF  P3OD1_OFF  //I2C_SDA开漏不使能
#endif

#if D_M_SCL==0   
#define I2C_SCL         P04
#define I2C_SCL_IN      P0OE4_IN   //I2C_SCL做输入口
#define I2C_SCL_OUT     P0OE4_OUT  //I2C_SCL做输出口
#define I2C_SCL_PH_ON   P0PH4_ON   //I2C_SCL上拉使能
#define I2C_SCL_PH_OFF  P0PH4_OFF  //I2C_SCL上拉不使能
#define I2C_SCL_PD_ON   P0PD4_ON   //I2C_SCL下拉使能
#define I2C_SCL_PD_OFF  P0PD4_OFF  //I2C_SCL下拉不使能
#define I2C_SCL_OD_ON   P0OD4_ON   //I2C_SCL开漏使能
#define I2C_SCL_OD_OFF  P0OD4_OFF  //I2C_SCL开漏不使能
#endif
#if D_M_SCL==1
#define I2C_SCL         P30
#define I2C_SCL_IN      P3OE0_IN   //I2C_SCL做输入口
#define I2C_SCL_OUT     P3OE0_OUT  //I2C_SCL做输出口
#define I2C_SCL_PH_ON   P3PH0_ON   //I2C_SCL上拉使能
#define I2C_SCL_PH_OFF  P3PH0_OFF  //I2C_SCL上拉不使能
#define I2C_SCL_PD_ON   P3PD0_ON   //I2C_SCL下拉使能
#define I2C_SCL_PD_OFF  P3PD0_OFF  //I2C_SCL下拉不使能
#define I2C_SCL_OD_ON   P3OD0_ON   //I2C_SCL开漏使能
#define I2C_SCL_OD_OFF  P3OD0_OFF  //I2C_SCL开漏不使能
#endif

#define I2CEN_EN       (1<<7)  //I2C使能
#define I2CEN_DIS      (0<<7)  //I2C不使能
#define I2CEN(x)       (x<<7)  //I2C使能位
#define I2CSTA_NOP     (0<<6)  //无任何操作
#define I2CSTA_STA     (1<<6)  //发送起始位
#define I2CSTA(x)      (x<<6)  //=1主机模式发送起始位使能，从机模式无效
#define I2CSTO_NOP     (0<<5)  //无任何操作
#define I2CSTO_STO     (1<<5)  //发送停止位
#define I2CSTO(x)      (x<<5)  //=1主机模式发送停止位使能，从机模式无效
#define I2CMOD_SALVE   (0<<4)  //从机模式
#define I2CMOD_MASTER  (1<<4)  //主机模式
#define I2CMOD(x)      (x<<4)  //主机从机模式选择,=1主机模式
#define I2CIE_DIS      (0<<3)  //I2C中断禁止
#define I2CIE_EN       (1<<3)  //I2C中断使能
#define I2CIE(x)       (x<<3)  //I2C中断使能位，=1中断使能
#define GC_NAK         (0<<0)  //对通用广播地址不应答
#define GC_ACK         (1<<0)  //对通用广播地址应答
#define GC(x)          (x<<0)  //通用广播应答位

#define GET_STASTA     (I2CSTATE&0x80)   //获取STASTA状态
#define GET_STOSTA     (I2CSTATE&0x40)   //获取STOSTA状态
#define GET_GCSTA      (I2CSTATE&0x20)   //获取GCSTA状态
#define GET_I2CESTA    (I2CSTATE&0x07)   //获取I2CESTA状态
#define GET_I2CIF      (IF0&0x80)        //获取I2CIF状态
#define GET_I2CWR      (I2CCON1&0x01)    //从机模式：=0 接收即主机写  =1发送即主机读

#define CLR_I2CIF      IF0 &=~0x80

#define I2CADR(x)      (x<<1)            //从机模式有效，从机地址
#define I2CSDAM(x)     (x<<5) 
#define I2CSCLM(x)     (x<<4) 
#endif